#pragma once

#include <string>
#include <vector>
#include <regex>
#include <cstdarg>
#include <iostream>
#include <memory>
#include <cstdio>
#include <cstdarg>

class String : public std::string
{
public:
	String();
	String(const String &str);
	String(const std::string& str);
	String(const char* str);
	String(const char c, int count = 1);

	static String format(const char* fmt, ...);

	String subFront(const char delimiter, bool last = true) const;
	String subAfter(const char delimiter, bool last = true) const;

	String lower() const;
	String upper() const;

	int toInt(size_t *_Idx = (size_t *)nullptr, int _Base = 10) const;
	long toLong(size_t *_Idx = (size_t *)nullptr, int _Base = 10) const;
	long long toLongLong(size_t *_Idx = (size_t *)nullptr, int _Base = 10) const;
	double toDouble(size_t *_Idx = (size_t *)nullptr) const;
	bool toBool() const;

	std::vector<String> split(const String &delimiter = " ") const;

	bool operator== (const String &str);
	bool operator== (const std::string &str);
	bool operator== (const char *str);

	bool operator!=(const String &str) const;
	bool operator!=(const std::string& str) const;
	bool operator!=(const char* str) const;

	String operator+ (const String &str) const;
	String operator+ (const std::string &str) const;
	String operator+ (const char *str) const;

	String &operator= (const String &str);
	String &operator= (const std::string &str);
	String &operator= (const char *str);

	String &operator+= (const String &str);
	String &operator+= (const std::string &str);
	String &operator+= (const char *str);
};
// Helper functions for type conversion (from string)
template<typename T>
T fromString(const String &str);

// Helper functions for type conversion (to string)
template<typename T>
String toString(const T& value);

// Template specializations for common types (from string)
template<>
inline int fromString<int>(const String &str)
{
	return std::stoi(str);
}

template<>
inline long fromString<long>(const String &str)
{
	return std::stol(str);
}

template<>
inline long long fromString<long long>(const String &str)
{
	return std::stoll(str);
}

template<>
inline unsigned long fromString<unsigned long>(const String &str)
{
	return std::stoul(str);
}

template<>
inline unsigned long long fromString<unsigned long long>(const String &str)
{
	return std::stoull(str);
}

template<>
inline float fromString<float>(const String &str)
{
	return std::stof(str);
}

template<>
inline double fromString<double>(const String &str)
{
	return std::stod(str);
}

template<>
inline bool fromString<bool>(const String &str)
{
	String lowerStr = str.lower();
	return (lowerStr == "true" || lowerStr == "1" || lowerStr == "yes" || lowerStr == "on");
}

template<>
inline String fromString<String>(const String &str)
{
	return str; // No conversion needed
}

template<>
inline std::string fromString<std::string>(const String &str)
{
	return std::string(str.c_str()); // No conversion needed
}

// Template specializations for common types (to string)

template<>
inline String toString<int>(const int &value)
{
	return std::to_string(value);
}

template<>
inline String toString<long>(const long &value)
{
	return std::to_string(value);
}

template<>
inline String toString<long long>(const long long &value)
{
	return std::to_string(value);
}

template<>
inline String toString<unsigned long>(const unsigned long &value)
{
	return std::to_string(value);
}

template<>
inline String toString<unsigned long long>(const unsigned long long &value)
{
	return std::to_string(value);
}

template<>
inline String toString<float>(const float &value)
{
	return std::to_string(value);
}

template<>
inline String toString<double>(const double &value)
{
	return std::to_string(value);
}

template<>
inline String toString<bool>(const bool& value)
{
	return value ? "true" : "false";
}

// --- 通用的 toString 模板 (放在最后) ---
// 对于没有特化的类型，尝试使用 stringstream
// 这可以处理任何重载了 operator<< 的类型
template<typename T>
String toString(const T& value)
{
	std::ostringstream oss;
	oss << value;
	return oss.str();
}

/**
 * @brief 流插入运算符重载：输出String对象
 *
 * @param os 输出流（如std::cout）
 * @param str 待输出的String对象（const引用，避免拷贝）
 *
 * @return 输出流（支持链式调用，如cout << str1 << str2）
 */
std::ostream &operator<<(std::ostream& os, const String &str);

/**
 * @brief 流提取运算符重载：读取输入到String对象
 *
 * @param is 输入流（如std::cin）
 * @param str 接收输入的String对象（非const引用，需修改其内容）
 *
 * @return 输入流（支持链式调用，如cin >> str1 >> str2）
 */
std::istream &operator>>(std::istream& is, String &str);

/**
 * @brief 重载std::getline：读取包含空格的字符串到String对象
 *
 * @param is 输入流（如std::cin）
 * @param str 待接收的String对象（非const引用）
 *
 * @return 输入流（支持链式调用）
 */
std::istream &getline(std::istream& is, String &str);

// 为String特化std::hash（必须放在std命名空间中）
namespace std
{
template <>
struct hash<String>
{
	// operator()接受const String&，返回size_t（哈希值）
	size_t operator()(const String &s) const noexcept
	{
		// 实现哈希计算（示例：使用std::hash<const char*>计算c_str()的哈希）
		return hash<const char *>()(s.c_str());
	}
};
}